package com.zhuoyue.web.controller.system;

import com.zhuoyue.common.constant.ResultCode;
import com.zhuoyue.common.core.controller.BaseController;
import com.zhuoyue.common.core.domain.AjaxResult;
import com.zhuoyue.common.core.domain.entity.SysDept;
import com.zhuoyue.common.core.page.TableDataInfo;
import com.zhuoyue.common.utils.poi.ExcelUtil;
import com.zhuoyue.system.common.group.ValidationGroups;
import com.zhuoyue.system.domain.TblAccountAuthorize;
import com.zhuoyue.system.domain.dto.AccountAuthorizeRepDTO;
import com.zhuoyue.system.domain.dto.AccountAuthorizeReqDTO;
import com.zhuoyue.system.domain.dto.ControllerResult;
import com.zhuoyue.system.domain.po.TblDevicePo;
import com.zhuoyue.system.domain.vo.HotelRoomDeviceCountExport;
import com.zhuoyue.system.domain.vo.TblDeviceVo;
import com.zhuoyue.system.domain.vo.TblHomeVo;
import com.zhuoyue.system.mapper.SysDeptMapper;
import com.zhuoyue.system.mapper.TblDeviceActionsMapper;
import com.zhuoyue.system.mapper.TblHomeMapper;
import com.zhuoyue.system.service.ITblDeviceService;
import com.zhuoyue.system.service.impl.TblAccountAuthorizeService;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 账号授权表(TblAccountAuthorize)表控制层
 *
 * @author makejava
 * @since 2021-08-31 11:41:27
 */
@RestController
@RequestMapping("system/account/authorize")
public class TblAccountAuthorizeController extends BaseController {
    /**
     * 服务对象
     */
    @Autowired
    private TblAccountAuthorizeService tblAccountAuthorizeService;


    @Autowired
    private SysDeptMapper deptMapper;

    @Autowired
    private TblHomeMapper tblHomeMapper;

    @Autowired
    private ITblDeviceService tblDeviceService;


    /**
     * 分页查询所有数据
     */
    @GetMapping("/list")
    public TableDataInfo selectList(TblAccountAuthorize accountAuthorize) {
        startPage();
        TableDataInfo dataTable = getAccountAuthorizeRepDTO(accountAuthorize);
        return dataTable;
    }

    /**
     * 导出酒店数据用户列表
     */
    @GetMapping("/export")
    public AjaxResult export(TblAccountAuthorize accountAuthorize) {
        TableDataInfo dataTable = getAccountAuthorizeRepDTO(accountAuthorize);
        ExcelUtil<AccountAuthorizeRepDTO> excelUtil = new ExcelUtil<>(AccountAuthorizeRepDTO.class);
        return excelUtil.exportExcel((List<AccountAuthorizeRepDTO>) dataTable.getRows(), "酒店数据");
    }


    @GetMapping
    public AjaxResult selectById(String id) {
        return AjaxResult.success(this.tblAccountAuthorizeService.selectByPrimaryKey(id));
    }

    /**
     * 获取获取Api的token信息
     *
     * @return
     */
    @PostMapping("/getTokenAndExpirationTime")
    public AjaxResult getTokenAndExpirationTime(@RequestBody ApiLoginRequest apiLoginRequest) {
        final String error = "error";
        String account = apiLoginRequest.getAccount();
        String password = apiLoginRequest.getPassword();
        SysDept sysDept = deptMapper.selectDeptById(apiLoginRequest.getDeptId());
        String orgCode = sysDept.getOrgCode();
        Map<String, Object> map = this.tblAccountAuthorizeService.requestApiToekn(account, password, orgCode);
        if (map.get(error) != null) {
            return AjaxResult.error(map.get(error).toString());
        }
        return AjaxResult.success(map);
    }


    /**
     * 新增数据
     *
     * @param reqDto 实体对象
     * @return 新增结果
     */
    @PostMapping
    public AjaxResult insert(@Validated(ValidationGroups.Insert.class) @RequestBody AccountAuthorizeReqDTO reqDto) {

        this.tblAccountAuthorizeService.insert(new TblAccountAuthorize().addDtoToDo(reqDto));
        return AjaxResult.success();
    }

    /**
     * 修改数据
     *
     * @param reqDto 实体对象
     * @return 修改结果
     */
    @PutMapping
    public AjaxResult update(@Validated(ValidationGroups.Update.class) @RequestBody AccountAuthorizeReqDTO reqDto) {
        this.tblAccountAuthorizeService.updateByPrimaryKeySelective(new TblAccountAuthorize().updateDtoToDo(reqDto));
        return AjaxResult.success();
    }

    /**
     * 删除数据
     *
     * @param idList 主键结合
     * @return 删除结果
     */
    @DeleteMapping
    public AjaxResult delete(@RequestBody List<String> idList) {
        this.tblAccountAuthorizeService.deleteButchById(idList);
        return AjaxResult.success();
    }

    /**
     * 获取数据并且封装
     *
     * @param accountAuthorize
     * @return
     */
    private TableDataInfo getAccountAuthorizeRepDTO(TblAccountAuthorize accountAuthorize) {
        List<TblAccountAuthorize> pageList = this.tblAccountAuthorizeService.getPageList(accountAuthorize);
        List<AccountAuthorizeRepDTO> accountAuthorizeRepDtoS = new ArrayList<>();
        pageList.forEach(f -> {
            AccountAuthorizeRepDTO accountAuthorizeRep = new AccountAuthorizeRepDTO();
            accountAuthorizeRep.doToDto(f);
            accountAuthorizeRepDtoS.add(accountAuthorizeRep);
        });
        TableDataInfo dataTable = getDataTable(pageList);
        dataTable.setRows(accountAuthorizeRepDtoS);
        return dataTable;
    }

    @Value("${zyzn.tokenCheckUrl}")
    private String tokenCheckUrl;

    @Autowired
    private TblDeviceActionsMapper actionsMapper;

    @PostMapping("/checkToken")
    public AjaxResult checkAppUserToken(String token) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.set("token", token);
        HttpEntity httpEntity = new HttpEntity<>(null, httpHeaders);
        RestTemplate restTemplate = new RestTemplate();
        ControllerResult result = restTemplate.exchange(tokenCheckUrl, HttpMethod.POST, httpEntity, ControllerResult.class).getBody();
        if (result.getMsgCode().equals(ResultCode.SUCCESS)) {
            return AjaxResult.success(result.getDataObject());
        }
        return AjaxResult.error("token校验失败");
    }

    @GetMapping("/hotel/rooms")
    public AjaxResult getHotelRooms(String account, String orgCode, String homeName) {
        // 查询家庭
        List<TblHomeVo> homeList = tblHomeMapper.getHomeByAccountAndOrgCode(account, orgCode, homeName);
        List<HotelRoomDeviceCountExport> hotelRoomDeviceCountExports = new ArrayList<>();

        // 根据家庭查询设备
        TblDevicePo devicePo = new TblDevicePo();
        for (TblHomeVo tblHomeVo : homeList) {
            // 需要判断是否已关闭的设备的ID列表
            List<String> checkSwitchStateDeviceIdList = new ArrayList<>();

            devicePo.setHomeId(tblHomeVo.getId());
            List<TblDeviceVo> deviceList = tblDeviceService.selectDeviceListByHomeId(devicePo);

            // 遍历设备列表, 获取设备在网状态数量
            //在线, 离线, 离网, 未关设备数量
            int count1 = 0, count2 = 0, count3 = 0, count4 = 0;
            for (TblDeviceVo tblDeviceVo : deviceList) {
                if ("0".equals(tblDeviceVo.getLwbz())) {
                    if (tblDeviceVo.getOnlineTime() != null && tblDeviceVo.getOnlineTime() != 0) {
                        if (tblDeviceVo.getDiffTime() < (tblDeviceVo.getOnlineTime() * 60)) {
                            count1++;
                        } else {
                            count2++;
                        }
                    }
                } else {
                    count3++;
                }

                if (isCloseAllDevice(tblDeviceVo.getDeviceType())) {
                    checkSwitchStateDeviceIdList.add(tblDeviceVo.getId());
                }
            }

            if (checkSwitchStateDeviceIdList.size() > 0) {
                count4 = actionsMapper.getOpenCountByDeviceId(checkSwitchStateDeviceIdList);
            }

            HotelRoomDeviceCountExport hotelRoomDeviceCountExport = new HotelRoomDeviceCountExport();
            hotelRoomDeviceCountExport.setHomeId(tblHomeVo.getId());
            hotelRoomDeviceCountExport.setHotelOrderNum(tblHomeVo.getHotelOrderNum());
            hotelRoomDeviceCountExport.setHomeName(tblHomeVo.getHomeName());
            hotelRoomDeviceCountExport.setDeviceTotal(deviceList.size());
            hotelRoomDeviceCountExport.setOnlineDeviceCount(count1);
            hotelRoomDeviceCountExport.setOfflineDeviceCount(count2);
            hotelRoomDeviceCountExport.setOffNetDeviceCount(count3);
            hotelRoomDeviceCountExport.setUnCloseDeviceCount(count4);

            hotelRoomDeviceCountExports.add(hotelRoomDeviceCountExport);
        }

        return AjaxResult.success(hotelRoomDeviceCountExports);
    }

    /**
     * 酒店房间的各设备数量导出
     *
     * @return
     */
    @GetMapping("/hotelRoomCount/export")
    public AjaxResult hotelRoomCountExport(String account, String orgCode, String homeName) {
        // 查询家庭
        List<TblHomeVo> homeList = tblHomeMapper.getHomeByAccountAndOrgCode(account, orgCode, homeName);
        List<HotelRoomDeviceCountExport> hotelRoomDeviceCountExports = new ArrayList<>();

        // 根据家庭查询设备
        TblDevicePo devicePo = new TblDevicePo();
        for (TblHomeVo tblHomeVo : homeList) {
            devicePo.setHomeId(tblHomeVo.getId());
            List<TblDeviceVo> deviceList = tblDeviceService.selectDeviceListByHomeId(devicePo);

            // 遍历设备列表, 获取设备在网状态数量
            //在线, 离线, 离网, 未关设备数量
            int count1 = 0, count2 = 0, count3 = 0, count4 = 0;
            for (TblDeviceVo tblDeviceVo : deviceList) {
                if ("0".equals(tblDeviceVo.getLwbz())) {
                    if (tblDeviceVo.getOnlineTime() != null && tblDeviceVo.getOnlineTime() != 0) {
                        if (tblDeviceVo.getDiffTime() < (tblDeviceVo.getOnlineTime() * 60)) {
                            count1++;
                        } else {
                            count2++;
                        }
                    }
                } else {
                    count3++;
                }

                if (isCloseAllDevice(tblDeviceVo.getDeviceType())) {
                    count4++;
                }
            }

            HotelRoomDeviceCountExport hotelRoomDeviceCountExport = new HotelRoomDeviceCountExport();
            hotelRoomDeviceCountExport.setHomeId(tblHomeVo.getId());
            hotelRoomDeviceCountExport.setHomeName(tblHomeVo.getHomeName());
            hotelRoomDeviceCountExport.setDeviceTotal(deviceList.size());
            hotelRoomDeviceCountExport.setOnlineDeviceCount(count1);
            hotelRoomDeviceCountExport.setOfflineDeviceCount(count2);
            hotelRoomDeviceCountExport.setOffNetDeviceCount(count3);
            hotelRoomDeviceCountExport.setUnCloseDeviceCount(count4);

            hotelRoomDeviceCountExports.add(hotelRoomDeviceCountExport);
        }
        ExcelUtil<HotelRoomDeviceCountExport> excelUtil = new ExcelUtil<>(HotelRoomDeviceCountExport.class);
        return excelUtil.exportExcel(hotelRoomDeviceCountExports, "酒店房间");
    }

    /**
     * 是否为一键全关设备
     *
     * @return
     */
    private boolean isCloseAllDevice(String deviceType) {
        if (deviceType.indexOf("_") > 0) {
            deviceType = deviceType.substring(0, deviceType.indexOf("_"));
        }

        boolean flag = false;
        switch (deviceType) {
            case "0FAA0502":
            case "0FAA0504":
            case "0FAA0602":
            case "0FAA0604":
            case "0FAA0702":
            case "0FAA0704":
            case "0FAA0804":
//            case "0FAA8A09":
            case "0FAA0D02":
            case "0FAA0D03":
            case "0FAA0D04":
            case "0FAB0602":
            case "0FAA0B02":
            case "0FAA0B03":
//            case "0FAA8A0A":
            case "0FAC0502":
            case "0FAA8A04":
            case "0FAA8A06":
            case "0FAA8A10":
                flag = true;
                break;
            default:
                break;
        }
        return flag;
    }
}

/**
 * Api登陆获取token
 */
@Data
class ApiLoginRequest {
    @NotBlank(message = "账号不能为空")
    private String account;
    @NotBlank(message = "密码不能为空")
    private String password;
    @NotBlank(message = "组织不能为空")
    private Long deptId;
}